/*
 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include <stdlib.h>

/* Prevent optimizer from fixing things we don't want fixed. */
#pragma GCC optimize("O0")

#define PW_LOG_MODULE_NAME "test"
#include "pw_log/log.h"

static int arr[] = {1, 2, 3};
static int *pp;

static void foo(void)
{
    int i[5] = {0};

    pp = &i[0]; // cppcheck-suppress danglingLifetime
}

void Test1(void)
{
    PW_LOG_INFO("*** Test 1");

    int *p = malloc(16);

    p[0] = 0;

    free(p);

    PW_LOG_INFO(" * Double free");
    free(p);

    PW_LOG_INFO(" * Use-after-free");
    arr[0] = p[0];
    p[0] = arr[1];

    PW_LOG_INFO(" * Dangling stack pointer access");
    foo();
    *pp = 0;
}

int Test2(void)
{
    PW_LOG_INFO("*** Test 2");

    char *memory = malloc(10);
    int64_t *p = (int64_t *)memory;
    *p = 0;

    PW_LOG_INFO(" * Array overrun");
    uint8_t c = *((uint8_t *)p);
    for (int j = 0; j < 10; j++) {
        p[j] = j;
    }
    free(p);

    PW_LOG_INFO(" * Use-after-free");
    int i = *p;
    return i + c;
}
